


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class BytesReceiver {

	public static final int FETCH_INTERVAL = 250;

	private String m_url;

	private String m_user;

	private String m_password;

	private PictureBytesHolder m_bytesHolder;

	public String m_encoding;

	public BytesReceiver(String url, String user, String password,
			PictureBytesHolder bytesHolder) {
		m_url = url;
		m_user = user;
		m_password = password;
		m_bytesHolder = bytesHolder;

		init();

		Thread thread = new Thread() {
			public void run() {
				receive();
			}
		};
		thread.start();
	}

	private void init() {
		String userPassword = m_user + ":" + m_password;

		m_encoding = new sun.misc.BASE64Encoder().encode(userPassword
				.getBytes());

	}

	public void receive() {

		try {

			URL helpURL = new URL("http://" + m_url
					+ "/nphMotionJpeg?Resolution=320x240&Quality=Standard");
			
			
			URLConnection uc = helpURL.openConnection();
			uc.setRequestProperty("Authorization", "Basic " + m_encoding);

			//System.out.println("Basic " + m_encoding);
			
			InputStream content = (InputStream) uc.getInputStream();
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] bytes = new byte[2048];
			int i;
			boolean sync = false;
			// Solange die TCP Verbindung besteht....
			while ((content.read(bytes)) != -1) {

				if (sync == false) {
					// Empfang synchronisieren

					// System.out.println("warte auf sync");
					i = checkForStartBytes(bytes);
					if (i > -1) {
						output.reset();
						output.write(bytes, i, bytes.length - i);
						sync = true;
					}
				} else {
					// Bild Daten empfangen

					// Abschliessen?
					i = checkForFFD9(bytes);
					if (i > -1) {
						// System.out.println("abschliessen");
						output.write(bytes, 0, i + 2);

						m_bytesHolder.setBytes(output.toByteArray());

						// wieder nach FFD8 (Startbytes) suchen
						i = checkForStartBytes(bytes);
						if (i > -1) {
							output.reset();
							output.write(bytes, i, bytes.length - i);
							sync = true;
						} else {
							sync = false;
						}

					} else {
						// Volles Byte empfangen
						// System.out.println("empfangen");
						output.write(bytes);
					}

				}

				Thread.sleep(FETCH_INTERVAL);
			}

			content.close();
			output.flush();
			output.close();


		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * Start des JPEG Bildes: Startbytes FFD8 -1;-40
	 * 
	 * @param bytes
	 * @return startByte
	 */
	public int checkForStartBytes(byte[] bytes) {

		for (int i = 0; i < bytes.length; i++) {

			// first FF
			if (bytes[i] == -1) {
				// check for following D8
				if (i + 1 < bytes.length && bytes[i + 1] == -40) {
					return i;
				}
			}
		}

		return -1;

	}

	// Ende des JPEG bildes: 2 Bytes FFD9: -1;-39
	public int checkForFFD9(byte[] bytes) {

		for (int i = 0; i < bytes.length; i++) {

			// first FF
			if (bytes[i] == -1) {
				// check for following D9

				if (i + 1 < bytes.length && bytes[i + 1] == -39) {
					return i;
				}
			}
		}

		return -1;

	}

	public void printBytes(byte[] bytes) {
		System.out.print("[");
		for (byte b : bytes) {
			System.out.print(b + ",");
		}
		System.out.println("]");

	}

	public void printBorderBytes(byte[] bytes, int borderDepth) {
		System.out.print("[");
		for (int i = 0; i < borderDepth; i++) {
			System.out.print(bytes[i] + ",");
		}
		System.out.print("...,");
		for (int i = borderDepth; i > -1; i--) {
			System.out.print(bytes[bytes.length - 1 - i] + ",");
		}

		System.out.println("]");

	}

}
